#include <stdio.h>
#include <unistd.h>
#include <assert.h>

int val = 100;


//子进程修改了val之后，父进程读取到的仍然是100，这里是发生了写时拷贝--暂且不谈，但是两个进程读取到的val的地址确还是一样的？？
//在真实的物理地址上，还是有虚拟地址，这里读取到的就是虚拟地址
//每个进程都是被OS以PCB链表的方式管理起来的，每个PCB也都指向的是虚拟的地址空间，这段空间是连续的，并且划分成不同的区域
//比如，栈，堆，全局，代码..区域


//写时拷贝：
//在fork函数返回的时候，就已经存在了父子进程，return的时候，假如fork先返回给父进程，那么id的值空间就先被父进程占用，等到再给子进程返回值的时候
//也就是再次向id写入值的时候，OS就会在物理地址空间上重新的为子进程分配一快地址发生写时拷贝，写时拷贝出来的大部分数据是继承父进程的，所以虚拟的地址父子进程是相同的
//但是实际上物理地址是不同的。
//
//另外管理虚拟地址和物理地址之间是通过页表进行的--之后再说
int main ()
{
  pid_t id = fork();
  assert(id >= 0);

  if(id == 0)
  {
    //child
    while(1)
    {
      printf("我是子进程 %d, 父进程: %d, val=%d, val地址: %p\n",getpid(), getppid(), val, &val);
      sleep(1);
      val = 200;//子进程修改全局变量val
    }
  }
  else
  {
    //parent
    while(1)
    {
      printf("我是父进程 %d, 父进程: %d, val=%d, val地址: %p\n",getpid(), getppid(), val, &val);
      sleep(1);
    }
  }

  return 0;
}
